#pragma once

#include "Segment.h"
#include <MyFC/GridControl.h>
#include <MyFC/Glyph.h>
#include "TreeControl.h"
#include "DLL.h"

namespace My {

class SegmentSet;
class SegmentSetRow;
class SegmentRow;
class Timeline;

class DLL_API SegmentRowControl : public Container  
{
	class Control : public My::Control
	{
	protected:
		SegmentRowControl &	m_Control;
		Timeline &			m_Timeline;
	public:
		Control(SegmentRowControl & c) 
			: m_Control(c), m_Timeline(c.m_Timeline)
			{ m_Control.Add(this); }
	};

	class LeftBracket : public Control	{
	private:
		int		m_StartPos;
		int		m_StartValue;
	public:
		LeftBracket(SegmentRowControl & c) : Control(c) { }
	public:
		virtual CRect Bounds() const;
		virtual String Hint() const 
			{ return "Segment Back End"; }
		virtual void HandleLeftDown(unsigned int flags, const CPoint & p);
		virtual bool HandleDragStart(unsigned int flags, const CPoint & p0, const CPoint & p);
		virtual void HandleDragEnd(unsigned int flags, const CPoint & p);
		virtual void HandleDragging(unsigned int flags, const CPoint & p);
	};

	class RightBracket : public Control {
	private:
		int		m_StartPos;
		int		m_StartValue;
	public:
		RightBracket(SegmentRowControl & c) : Control(c) { }
	public:
		virtual CRect Bounds() const;
		virtual String Hint() const 
			{ return "Segment Front End"; }
		virtual void HandleLeftDown(unsigned int flags, const CPoint & p);
		virtual bool HandleDragStart(unsigned int flags, const CPoint & p0, const CPoint & p);
		virtual void HandleDragEnd(unsigned int flags, const CPoint & p);
		virtual void HandleDragging(unsigned int flags, const CPoint & p);
	};

private:
	SegmentSetRow &		m_SegmentSetRow;
	Timeline &			m_Timeline;
	Segment *			m_pSegment;
	int					m_Index;
	int					m_Gap;
	SysColorGlyph		m_Left;
	SysColorGlyph		m_Right;
	SysColorGlyph		m_Mask;
	SysColorGlyph		m_MaskPressed;
	SysColorGlyph		m_MaskGrayed;
	CBitmap				m_DarkOrangeRipple;
	CBitmap				m_LightOrangeRipple;
	CBitmap				m_DarkBlueRipple;
	CBitmap				m_LightBlueRipple;
	LeftBracket			m_LeftBracket;
	RightBracket		m_RightBracket;
	CPoint				m_BrushOrg;
	Span				m_TimeSpan;
public:
	Segment & GetSegment() const;
	int GetIndex() const
		{ return m_Index; }
private:
	Span GetTimeSpan() const;
	void SetTimeSpan(Span s);
	void UpdateTimeSpan();
	int GetOrigin() const;
	CRect GetUnionSpanRect() const;
private:
	int TimeToClient(double time) const;
	double ClientToTime(int x) const;
	SegmentSet * GetSegments() const; 
public:
	virtual CRect Bounds() const;
	virtual String Hint() const;
public:
	SegmentRowControl(SegmentSetRow & r, int index);
	~SegmentRowControl();
public:
	bool IsEmpty() const;
	void StartAnimation();
	void StopAnimation();
	void Animate();
protected:
	virtual void ProcessEvent(My::Event &);
	virtual void Paint(CDC * pDC, const CRect & r);
	virtual void HandleKeyDown(unsigned int key, unsigned int count, unsigned int flags);
	virtual void HandleLeftDown(unsigned int flags, const CPoint & p);
	virtual void HandleLeftDoubleClick(unsigned int flags, const CPoint &p);
	virtual bool HandleDragStart(unsigned int flags, const CPoint & p0, const CPoint & p);
	virtual void HandleDragEnd(unsigned int flags, const CPoint & p);
	virtual void HandleDragging(unsigned int flags, const CPoint & p);
	virtual void HandleFocus();
	virtual void HandleUnfocus();
public:
	virtual void OnInitialUpdate();
	virtual void OnTimeSpanChanged();
	virtual void OnDataSpanChanged();
	virtual void OnStatusChanged();
};

class DLL_API SegmentRow : 
	public GridRow,
	public TreeRow
{
public:
	SegmentRow(SegmentSetRow &, int index);
	~SegmentRow();
public:
	virtual String GetCaption() const;
	virtual void HandlePaint(CDC *, const CRect &);
	virtual void HandleLeftDown(unsigned int, const CPoint &);
	virtual void PaintCell(CDC *, const CRect & rClip, const Column &, const CRect & rCell);
	virtual void ProcessEvent(Event &);
private:
	SegmentSetRow &		m_Owner;
	SegmentRowControl	m_Control;
};

} // My
